package com.hezhi.project.weixin.utils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.hezhi.HomeSchoolApplication;
import com.hezhi.common.utils.CommonUtil;
import com.hezhi.common.utils.DateUtils2;
import com.hezhi.framework.config.MyConfig;

/**
 * 微信公众号设置
 * @author 徐伦
 *
 */
@Component
public class WeChatUtils {
	
	private static Logger logger = LoggerFactory.getLogger(WeChatUtils.class);

	public static JSONObject CODE_TO_ACCESSTOKEN = null;
	private final static String GET_METHOD = "GET";
	private final static String POST_METHOD = "POST";
	private final static Map<String, Object> MAP = new HashMap<String, Object>();
	
	//获取token
	private final static String URL_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
	//获取二维码图片ticket
	private final static String URL_QRCODE_CREATE = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKENPOST";
	//显示、下载二维码
	//private final static String URL_SHOWQRCODE = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET";
	//跳转微信获取code
	public final static String URL_AUTHORIZE="https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
	//获取微信用户openid等信息
	private final static String URL_ACCESS_TOKEN = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
	//检验授权凭证（access_token）是否有效(获取用户信息的access_token)
	private final static String URL_AUTH = "https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID";
	//刷新access_token(获取用户信息的access_token)
	private final static String URL_REFRESH_TOKEN = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";
	//获取用户详细信息
	private final static String URL_SNSAPI_USERINFO = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
	//获取JSSDKticket
	private final static String URL_GETTICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
	//
	private final static String URL_USERINFO = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
	
	/**
	 * 从微信获取token
	 */
	private static void connect_getToken(){
		String requestUrl = URL_TOKEN.replace("APPID", HomeSchoolApplication.ac.getBean(MyConfig.class).getWeixin().get("appid")).replace("APPSECRET", HomeSchoolApplication.ac.getBean(MyConfig.class).getWeixin().get("appsecret"));
		JSONObject j = CommonUtil.httpsRequest(requestUrl, GET_METHOD, null);
		if(j.containsKey("access_token")){
			MAP.put("access_token", j.get("access_token"));
			MAP.put("expires_date", DateUtils2.getDateTime());
		}
		logger.info(JSONObject.toJSONString(j));
	}
	
	/**
	 * 获取服务器内存中的有效token
	 * @return
	 */
	public static String getToken(){
		if(MAP.get("expires_date") == null){
			connect_getToken();
		}
		long expires_date = DateUtils2.pastSeconds(DateUtils2.parseDate(MAP.get("expires_date")));
		//判断服务器中的token是否过了有效期
		if(expires_date>7200){
			connect_getToken();
		}
		return MAP.get("access_token").toString();
	}
	
	/**
	 * 获取永久二维码
	 */
	public static void connect_qrcode_create(){
		String requestUrl = URL_QRCODE_CREATE.replace("TOKENPOST", getToken());
		String outputStr = "{\"action_name\": \"QR_LIMIT_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \"test\"}}}";
		JSONObject j = CommonUtil.httpsRequest(requestUrl, POST_METHOD, outputStr);
		System.err.println(j);
	}
	
	/**
	 * 获取微信用户的openid
	 * @param code
	 * @return
	 */
	public static JSONObject connect_getOpenid(String code){
		String requestUrl = URL_ACCESS_TOKEN.replace("APPID", HomeSchoolApplication.ac.getBean(MyConfig.class).getWeixin().get("appid")).replace("SECRET", HomeSchoolApplication.ac.getBean(MyConfig.class).getWeixin().get("appsecret")).replace("CODE", code);
		JSONObject j = CommonUtil.httpsRequest(requestUrl, POST_METHOD, null);
		j.put("createDate", new Date().getTime());
		CODE_TO_ACCESSTOKEN = j;
		if(j.containsKey("openid")){
			logger.info(JSONObject.toJSONString(j));
			return j;
		}
		logger.info(JSONObject.toJSONString(j));
		return null;
	}
	
	/**
	 * 检查获取用户信息的access_token是否有效
	 * @return
	 */
	public static boolean inspect_accessToken(){
		JSONObject j = CODE_TO_ACCESSTOKEN;
		if(j == null){
			return false;
		}else{
			if((new Date().getTime()-j.getLong("createDate"))<7200){
				return true;
			}
			String requestUrl = URL_AUTH.replace("ACCESS_TOKEN", j.getString("access_token")).replace("OPENID", j.getString("openid"));
			JSONObject json = CommonUtil.httpsRequest(requestUrl, GET_METHOD, null);
			if(json.getString("errcode").equals("0")){
				return true;
			}else{
				return false;
			}
		}
	}
	
	/**
	 * 重新获取用户信息的access_token
	 */
	public static JSONObject connect_refreshToken(){
		JSONObject j = CODE_TO_ACCESSTOKEN;
		if(inspect_accessToken()){
			return j;
		}else{
			String requestUrl = URL_REFRESH_TOKEN.replace("APPID", j.getString("openid")).replace("REFRESH_TOKEN", j.getString("refresh_token"));
			JSONObject json = CommonUtil.httpsRequest(requestUrl, POST_METHOD, null);
			j.put("createDate", new Date().getTime());
			CODE_TO_ACCESSTOKEN = json;
			return json;
		}
	}
	
	/**
	 * 获取用户详细信息
	 * @return
	 */
	public static JSONObject connect_userinfo(){
		JSONObject j = connect_refreshToken();
		String requestUrl = URL_SNSAPI_USERINFO.replace("ACCESS_TOKEN", j.getString("access_token")).replace("OPENID", j.getString("openid"));
		JSONObject json = CommonUtil.httpsRequest(requestUrl, GET_METHOD, null);
		return json;
	}
	
	/**
	 * 从微信获取Ticket
	 */
	private static void connect_getTicket(){
		String requestUrl = URL_GETTICKET.replace("ACCESS_TOKEN", getToken());
		JSONObject j = CommonUtil.httpsRequest(requestUrl, GET_METHOD, null);
		if(j.containsKey("ticket")){
			MAP.put("ticket", j.get("ticket"));
			MAP.put("ticket_date", DateUtils2.getDateTime());
		}
		logger.info(JSONObject.toJSONString(j));
	}
	
	/**
	 * 获取服务器内存中的有效Ticket
	 * @return
	 */
	public static String getTicket(){
		if(MAP.get("ticket_date") == null){
			connect_getTicket();
		}
		long ticket_date = DateUtils2.pastSeconds(DateUtils2.parseDate(MAP.get("ticket_date")));
		//判断服务器中的token是否过了有效期
		if(ticket_date>7200){
			connect_getTicket();
		}
		return MAP.get("ticket").toString();
	}
	
	/**
	 * 获取用户详细信息
	 * @param openId
	 * @return
	 */
	public static JSONObject getUserInfo(String openId){
		String requestUrl = URL_USERINFO.replace("ACCESS_TOKEN", getToken()).replace("OPENID", openId);
		JSONObject j = CommonUtil.httpsRequest(requestUrl, GET_METHOD, null);
		return j;
	} 
	
	/** 
	  * 将emoji表情替换成空串 
	  *   
	  * @param source 
	  * @return 过滤后的字符串 
	  */  
	 public static String filterEmoji(String source) {  
		  if (source != null && source.length() > 0) {  
		   return source.replaceAll("[\ud800\udc00-\udbff\udfff\ud800-\udfff]", "");  
		  } else {  
		   return source;  
		  }  
	}
	 
	 /**
		 * 获取请求的根路径
		 * @param request
		 * @return
	 */
	public static String getProjectPath(HttpServletRequest request){
		String url = request.getScheme()+"://" + request.getServerName() //服务器地址  
				+ (80 == request.getServerPort()?"":":"+request.getServerPort()) //端口号  
                + request.getContextPath();      //项目名称  
		return url;
	}
	
}
